import geopandas as gpd
import altair as alt
import pandas as pd
trends = pd.read_csv("population_trends.csv")
trends.head()
| region | year | rate | |
|---|---|---|---|
| 0 | Ukraine | 1989 | 1.7 |
| 1 | Ukraine | 1990 | 0.5 |
| 2 | Ukraine | 1991 | -0.8 |
| 3 | Ukraine | 1992 | -2.0 |
| 4 | Ukraine | 1993 | -3.5 |
ukraine = gpd.read_file('ukraine.json')
ukraine.head()
| GID_0 | NAME_0 | GID_1 | NAME_1 | VARNAME_1 | NL_NAME_1 | TYPE_1 | ENGTYPE_1 | CC_1 | HASC_1 | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | UKR | Ukraine | UKR.1_1 | Cherkasy | Cherkas'ka Oblast'|Cherkasskaya Oblast'|Cherkassy | None | Oblast' | Region | None | UA.CK | MULTIPOLYGON (((31.32614 48.74507, 31.31716 48... |
| 1 | UKR | Ukraine | UKR.2_1 | Chernihiv | Chernigov|Tschernigow | None | Oblast' | Region | None | UA.CH | MULTIPOLYGON (((33.09283 50.50966, 33.09261 50... |
| 2 | UKR | Ukraine | UKR.3_1 | Chernivtsi | Chernivets'ka Oblast'|Chernovitskaya Oblast'|C... | None | Oblast' | Region | None | UA.CV | MULTIPOLYGON (((24.93280 47.72794, 24.93301 47... |
| 3 | UKR | Ukraine | UKR.4_1 | Crimea | Crimée|Criméia|Krim|Krymskaya Respublika|Respu... | None | Autonomous Republic | Autonomous Republic | None | UA.KR | MULTIPOLYGON (((33.79291 44.39153, 33.79465 44... |
| 4 | UKR | Ukraine | UKR.5_1 | Dnipropetrovs'k | Dnipropetrovsk|Dniepropietrovsk|Dnjepropetrowsk | None | Oblast' | Region | None | UA.DP | MULTIPOLYGON (((33.93176 47.48407, 33.92332 47... |
trends = trends[trends['region'] != 'Ukraine'] # clean up data
latest = trends[trends['year'] == trends['year'].max()]
latest
| region | year | rate | |
|---|---|---|---|
| 61 | Crimea | 2019 | NaN |
| 92 | Vinnytsya | 2019 | -7.9 |
| 123 | Volyn | 2019 | -2.8 |
| 154 | Dnipropetrovs'k | 2019 | -8.9 |
| 185 | Donets'k | 2019 | NaN |
| 216 | Zhytomyr | 2019 | -8.5 |
| 247 | Transcarpathia | 2019 | -2.0 |
| 278 | Zaporizhzhya | 2019 | -9.6 |
| 309 | Ivano-Frankivs'k | 2019 | -4.0 |
| 340 | Kyiv | 2019 | -8.1 |
| 371 | Kirovohrad | 2019 | -9.6 |
| 402 | Luhans'k | 2019 | NaN |
| 433 | L'viv | 2019 | -4.3 |
| 464 | Mykolayiv | 2019 | -8.1 |
| 495 | Odesa | 2019 | -5.1 |
| 526 | Poltava | 2019 | -9.9 |
| 557 | Rivne | 2019 | -1.6 |
| 588 | Sumy | 2019 | -10.2 |
| 619 | Ternopil' | 2019 | -6.6 |
| 650 | Kharkiv | 2019 | -8.4 |
| 681 | Kherson | 2019 | -7.4 |
| 712 | Khmel'nyts'kyy | 2019 | -7.5 |
| 743 | Cherkasy | 2019 | -10.0 |
| 774 | Chernivtsi | 2019 | -3.1 |
| 805 | Chernihiv | 2019 | -12.5 |
| 836 | Kyiv City | 2019 | -0.2 |
| 867 | Sevastopol' | 2019 | NaN |
ukraine = ukraine[['NAME_1', 'geometry']]
ukraine.columns = ['region', 'geometry'] # need to rename columns for transform_lookup
rate_map = alt.Chart(ukraine, title='Population rate of 2019 by region').transform_lookup(
lookup = 'region',
from_ = alt.LookupData(data = latest,
key = 'region',
fields=['rate'])
).mark_geoshape(color ='lightgray', stroke = 'white', strokeWidth = 1
).encode(
color = alt.Color('rate:Q', scale=alt.Scale(scheme='reds', reverse = True)),
tooltip = [
alt.Tooltip('region:N'),
alt.Tooltip('rate:Q')
]
) + alt.Chart(ukraine[ukraine['region'].isin(latest[latest['rate'].isna()]['region'].tolist())]).mark_geoshape(fill = 'lightgray', stroke = 'white', strokeWidth = 1)
rate_map = rate_map.properties(width = 600, height = 400)
rate_map
trends = trends[(trends['year'] >1988) & (trends['year'] < 2020)]
linear = alt.Chart(trends, title='Population increase\decrease rate by regions over years').mark_line().encode(
x = alt.X('year:Q', title='Year'),
y = alt.Y('rate:Q', title="Population change rate"),
color = alt.Color('region:N', title='Region'),
tooltip = [alt.Tooltip('region:N', title='Region:')]
).properties(width = 600, height = 400)
linear
alt.hconcat(rate_map, linear)